home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / frasr182.zip / ZOOM.C < prev   
C/C++ Source or Header  |  1993-01-05  |  19KB  |  540 lines

  1. /*
  2.     zoom.c - routines for zoombox manipulation and for panning
  3.  
  4. */
  5.  
  6. #include <float.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "fractint.h"
  11. #include "prototyp.h"
  12.  
  13. /* screen dimensions here are (1.0,1.0) corresponding to (xdots-1,ydots-1) */
  14. extern double zbx,zby;           /* topleft of unrotated zoombox  */
  15. extern double zwidth,zdepth,zskew; /* zoombox size & shape        */
  16. extern int zrotate;           /* * 2.5 degree increments        */
  17. extern int boxcount,boxx[],boxy[]; /* co-ords of each zoombox pixel */
  18. extern int xdots,ydots,sxdots,sydots,sxoffs,syoffs;
  19. extern double dxsize,dysize;       /* xdots-1, ydots-1            */
  20. extern double xxmin,yymin,xxmax,yymax,xx3rd,yy3rd;
  21. extern double sxmin,symin,sxmax,symax,sx3rd,sy3rd;
  22. /* top      left    corner of screen is (xxmin,yymax) */
  23. /* bottom left    corner of screen is (xx3rd,yy3rd) */
  24. /* bottom right corner of screen is (xxmax,yymin) */
  25. extern double plotmx1,plotmx2,plotmy1,plotmy2;
  26.  
  27. extern int  calc_status;       /* status of calculations */
  28. extern int  fractype;           /* fractal type */
  29. extern char stdcalcmode;       /* '1', '2', 'g', 'b', or 't' */
  30. extern int  num_worklist;       /* resume worklist for standard engine */
  31. extern struct workliststuff worklist[MAXCALCWORK];
  32. extern char dstack[4096];       /* common temp, used for get_line/put_line */
  33. extern int  potflag;
  34. extern int  pot16bit;
  35. extern float finalaspectratio;
  36. extern float  screenaspect;
  37.  
  38. struct coords {
  39.     int x,y;
  40.     };
  41.  
  42. #define PIXELROUND 0.00001
  43.  
  44. static void _fastcall drawlines(struct coords, struct coords, int, int);
  45. static void _fastcall addbox(struct coords);
  46. static void _fastcall zmo_calc(double, double, double *, double *);
  47. static int  check_pan();
  48. static void fix_worklist();
  49. static void _fastcall move_row(int fromrow,int torow,int col);
  50.  
  51. void drawbox(int drawit)
  52. {   struct coords tl,bl,tr,br; /* dot addr of topleft, botleft, etc */
  53.     double tmpx,tmpy,dx,dy,rotcos,rotsin,ftemp1,ftemp2;
  54.     double fxwidth,fxskew,fydepth,fyskew,fxadj;
  55.  
  56.     if (zwidth==0) { /* no box to draw */
  57.     if (boxcount!=0) { /* remove the old box from display */
  58.         clearbox();   /* asm routine */
  59.         boxcount = 0; }
  60.     reset_zoom_corners();
  61.     return; }
  62.  
  63.     ftemp1 = PI*zrotate/72; /* convert to radians */
  64.     rotcos = cos(ftemp1);   /* sin & cos of rotation */
  65.     rotsin = sin(ftemp1);
  66.  
  67.     /* do some calcs just once here to reduce fp work a bit */
  68.     fxwidth = sxmax-sx3rd;
  69.     fxskew  = sx3rd-sxmin;
  70.     fydepth = sy3rd-symax;
  71.     fyskew  = symin-sy3rd;
  72.     fxadj   = zwidth*zskew;
  73.  
  74.     /* calc co-ords of topleft & botright corners of box */
  75.     tmpx = zwidth/-2+fxadj; /* from zoombox center as origin, on xdots scale */
  76.     tmpy = zdepth*finalaspectratio/2;
  77.     dx = (rotcos*tmpx - rotsin*tmpy) - tmpx; /* delta x to rotate topleft */
  78.     dy = tmpy - (rotsin*tmpx + rotcos*tmpy); /* delta y to rotate topleft */
  79.     /* calc co-ords of topleft */
  80.     ftemp1 = zbx + dx + fxadj;
  81.     ftemp2 = zby + dy/finalaspectratio;
  82.     tl.x   = ftemp1*(dxsize+PIXELROUND); /* screen co-ords */
  83.     tl.y   = ftemp2*(dysize+PIXELROUND);
  84.     xxmin  = sxmin + ftemp1*fxwidth + ftemp2*fxskew; /* real co-ords */
  85.     yymax  = symax + ftemp2*fydepth + ftemp1*fyskew;
  86.     /* calc co-ords of bottom right */
  87.     ftemp1 = zbx + zwidth - dx - fxadj;
  88.     ftemp2 = zby - dy/finalaspectratio + zdepth;
  89.     br.x   = ftemp1*(dxsize+PIXELROUND);
  90.     br.y   = ftemp2*(dysize+PIXELROUND);
  91.     xxmax  = sxmin + ftemp1*fxwidth + ftemp2*fxskew;
  92.     yymin  = symax + ftemp2*fydepth + ftemp1*fyskew;
  93.  
  94.     /* do the same for botleft & topright */
  95.     tmpx = zwidth/-2 - fxadj;
  96.     tmpy = 0.0-tmpy;
  97.     dx = (rotcos*tmpx - rotsin*tmpy) - tmpx;
  98.     dy = tmpy - (rotsin*tmpx + rotcos*tmpy);
  99.     ftemp1 = zbx + dx - fxadj;
  100.     ftemp2 = zby + dy/finalaspectratio + zdepth;
  101.     bl.x   = ftemp1*(dxsize+PIXELROUND);
  102.     bl.y   = ftemp2*(dysize+PIXELROUND);
  103.     xx3rd  = sxmin + ftemp1*fxwidth + ftemp2*fxskew;
  104.     yy3rd  = symax + ftemp2*fydepth + ftemp1*fyskew;
  105.     ftemp1 = zbx + zwidth - dx + fxadj;
  106.     ftemp2 = zby - dy/finalaspectratio;
  107.     tr.x   = ftemp1*(dxsize+PIXELROUND);
  108.     tr.y   = ftemp2*(dysize+PIXELROUND);
  109.  
  110.     if (boxcount!=0) { /* remove the old box from display */
  111.     clearbox();   /* asm routine */
  112.     boxcount = 0; }
  113.  
  114.     if (drawit) { /* caller wants box drawn as well as co-ords calc'd */
  115. #ifndef XFRACT
  116.     /* build the list of zoom box pixels */
  117.     addbox(tl); addbox(tr);           /* corner pixels */
  118.     addbox(bl); addbox(br);
  119.     drawlines(tl,tr,bl.x-tl.x,bl.y-tl.y); /* top & bottom lines */
  120.     drawlines(tl,bl,tr.x-tl.x,tr.y-tl.y); /* left & right lines */
  121. #else
  122.         boxx[0] = tl.x + sxoffs;
  123.         boxy[0] = tl.y + syoffs;
  124.         boxx[1] = tr.x + sxoffs;
  125.         boxy[1] = tr.y + syoffs;
  126.         boxx[2] = br.x + sxoffs;
  127.         boxy[2] = br.y + syoffs;
  128.         boxx[3] = bl.x + sxoffs;
  129.         boxy[3] = bl.y + syoffs;
  130.         boxcount = 1;
  131. #endif
  132.     dispbox();                  /* asm routine to paint it */
  133.     }
  134.     }
  135.  
  136. static void _fastcall drawlines(struct coords fr, struct coords to,
  137.                 int dx, int dy)
  138. {   int xincr,yincr,ctr;
  139.     int altctr,altdec,altinc;
  140.     struct coords tmpp,line1,line2;
  141.  
  142.     if (abs(to.x-fr.x) > abs(to.y-fr.y)) { /* delta.x > delta.y */
  143.     if (fr.x>to.x) { /* swap so from.x is < to.x */
  144.         tmpp = fr; fr = to; to = tmpp; }
  145.     xincr = (to.x-fr.x)*4/sxdots+1; /* do every 1st, 2nd, 3rd, or 4th dot */
  146.     ctr = (to.x-fr.x-1)/xincr;
  147.     altdec = abs(to.y-fr.y)*xincr;
  148.     altinc = to.x-fr.x;
  149.     altctr = altinc/2;
  150.     yincr = (to.y>fr.y)?1:-1;
  151.     line2.x = (line1.x = fr.x) + dx;
  152.     line2.y = (line1.y = fr.y) + dy;
  153.     while (--ctr>=0) {
  154.         line1.x += xincr;
  155.         line2.x += xincr;
  156.         altctr -= altdec;
  157.         while (altctr<0) {
  158.         altctr    += altinc;
  159.         line1.y += yincr;
  160.         line2.y += yincr;
  161.         }
  162.         addbox(line1);
  163.         addbox(line2);
  164.         }
  165.     }
  166.  
  167.     else { /* delta.y > delta.x */
  168.     if (fr.y>to.y) { /* swap so from.y is < to.y */
  169.         tmpp = fr; fr = to; to = tmpp; }
  170.     yincr = (to.y-fr.y)*4/sydots+1; /* do every 1st, 2nd, 3rd, or 4th dot */
  171.     ctr = (to.y-fr.y-1)/yincr;
  172.     altdec = abs(to.x-fr.x)*yincr;
  173.     altinc = to.y-fr.y;
  174.     altctr = altinc/2;
  175.     xincr = (to.x>fr.x) ? 1 : -1;
  176.     line2.x = (line1.x = fr.x) + dx;
  177.     line2.y = (line1.y = fr.y) + dy;
  178.     while (--ctr>=0) {
  179.         line1.y += yincr;
  180.         line2.y += yincr;
  181.         altctr  -= altdec;
  182.         while (altctr<0) {
  183.         altctr    += altinc;
  184.         line1.x += xincr;
  185.         line2.x += xincr;
  186.         }
  187.         addbox(line1);
  188.         addbox(line2);
  189.         }
  190.     }
  191.     }
  192.  
  193. static void _fastcall addbox(struct coords point)
  194. {
  195.     point.x += sxoffs;
  196.     point.y += syoffs;
  197.     if (point.x >= 0 && point.x < sxdots && point.y >= 0 && point.y < sydots) {
  198.     boxx[boxcount] = point.x;
  199.     boxy[boxcount] = point.y;
  200.     ++boxcount;
  201.     }
  202.     }
  203.  
  204. void moveboxf(double dx, double dy)
  205. {   int align,row,col;
  206.     align = check_pan();
  207.     if (dx!=0.0) {
  208.     if ((zbx += dx) + zwidth/2 < 0)  /* center must stay onscreen */
  209.         zbx = zwidth/-2;
  210.     if (zbx + zwidth/2 > 1)
  211.         zbx = 1.0 - zwidth/2;
  212.     if (align != 0
  213.       && ((col = zbx*(dxsize+PIXELROUND)) & (align-1)) != 0) {
  214.         if (dx > 0) col += align;
  215.         col -= col & (align-1); /* adjust col to pass alignment */
  216.         zbx = (double)col/dxsize; }
  217.     }
  218.     if (dy!=0.0) {
  219.     if ((zby += dy) + zdepth/2 < 0)
  220.         zby = zdepth/-2;
  221.     if (zby + zdepth/2 > 1)
  222.         zby = 1.0 - zdepth/2;
  223.     if (align != 0
  224.       && ((row = zby*(dysize+PIXELROUND)) & (align-1)) != 0) {
  225.         if (dy > 0) row += align;
  226.         row -= row & (align-1);
  227.         zby = (double)row/dysize; }
  228.     }
  229.     }
  230.  
  231. static void _fastcall chgboxf(double dwidth, double ddepth)
  232. {
  233.     if (zwidth+dwidth > 1)
  234.     dwidth = 1.0-zwidth;
  235.     if (zwidth+dwidth < 0.05)
  236.     dwidth = 0.05-zwidth;
  237.     zwidth += dwidth;
  238.     if (zdepth+ddepth > 1)
  239.     ddepth = 1.0-zdepth;
  240.     if (zdepth+ddepth < 0.05)
  241.     ddepth = 0.05-zdepth;
  242.     zdepth += ddepth;
  243.     moveboxf(dwidth/-2,ddepth/-2); /* keep it centered & check limits */
  244.     }
  245.  
  246. void resizebox(int steps)
  247. {
  248.     double deltax,deltay;
  249.     if (zdepth*screenaspect > zwidth) { /* box larger on y axis */
  250.     deltay = steps * 0.036 / screenaspect;
  251.     delt